#include<cstdlib>
#include<cstdio>
#include<ctime>
#include<iostream>
#include<fstream>
#include<cmath>
#include<string>
#include "generator.h"
#include "bucket.h"
using namespace std;
#define window 10000
#define eval_every 100000
// 公共参数
#define gnerate_num 1000000
#define digit_num 7

//用数组表示某一时刻的总和
int realsum[gnerate_num + 1] = { 0 };
void build(){
    bool flag;                              //读入二进制数
    int realnum = 0;                        //读入十进制数

    int time = 0;

    //二进制数输入文件流与十进制数文件输入流
    ifstream ifile_bin[digit_num], ifile_dec;
    ofstream ofile;                         //创建1个输出文件流
    pbucket heads[digit_num];                //头指针数组，heads[i]指向空的头节点，heads[i]->next为第一个bucket
    pbucket tails[digit_num];                //尾插法工作指针
    //初始化
    for(int i=0;i < digit_num;i++){
        heads[i] = (pbucket)malloc(sizeof(bucket));
        tails[i] = heads[i];
    }  
    pbucket temp;                           //暂存输入数据流的指针
    //打开对应文件
    ofile.open("../output.csv");
    ofile <<"timestamp"<<","<<"estimate"<<","<<"truth"<<endl;
    ifile_dec.open("../data/int_1000000.dat");
    for(int i = 0;i < digit_num;i++){
        ifile_bin[i].open("../data/bin_1000000_"+to_string(i)+".dat");
    }
    //读取文件流
    while(ifile_dec.peek() != EOF){
        time ++;
        ifile_dec>>realnum;
        realsum [time] = realsum [time-1] + realnum;    
        for(int i = 0;i < digit_num; i++){
            ifile_bin[i] >> flag;
            if(flag == 1){
                //带头节点的双线链表尾插
                temp = (pbucket)malloc(sizeof(bucket));
                temp->next = NULL;
                temp->prev = NULL;
                temp->size = 1;
                temp->timestamp = time;
                tails[i]->next = temp;
                temp->prev = tails[i];
                tails[i] = temp;
                //合并链表
                merge(tails[i],1);
                //去掉超出窗口的bucket 
                clip(time-window,heads[i]);                            
            }
        }
        //存储结果
        if(time % eval_every == 0){
            int est_res = calculate_DGIM(heads);
            ofile<<time <<","<< est_res <<","<< realsum[time] - realsum[time - window] <<endl;
            cout << "Timestamp=" << time << endl;
            cout << "\tesitimate:" << est_res << endl;
            cout << "\ttruth:" << realsum[time] - realsum[time - window] << endl;
        }
        //求当时间戳为 10,000、500,000、1,000,000 时，打印出 7 个二进制数据流分桶情况
        if (time == 10000 || time == 500000 || time == 1000000) {
            show_result(time, heads);
        }
    }
    //销毁链表
    for(int i=0;i<digit_num;i++){
        destroy(heads[i]);
    }
    //关闭文件
    ofile.close();
    ifile_dec.close();
    for(int i=0;i < digit_num;i++){
        ifile_bin[i].close();
    }
}
int main(){
    string cmd;
    //让用户输入g或者r来表示生成随机数据或者启动DGIM算法
    cout << "choose to generate data or run DGIM algorithm, please input g or r"<< endl;
    cin >> cmd;
    if (cmd == "g") {
        //随机生成数据
        rand_generator();
        cout << "generation rand data in project_dir/data compeletd" << endl;
    }
    else if (cmd == "r") {
        //启动DGIM算法
        cout << "running DGIM algorithm" << endl;
        build();
    }
    else {
        //无效输入
        cout << "unrecognized command, exiting" << endl;
    }
    /*rand_generator();
    build();*/
    system("pause");//按任意键继续
    return 0;
}